/*!
 * \file IDataWriter.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 数据写入接口定义
 * \details 定义了数据写入模块的核心接口，包括数据写入回调、历史数据导出器和主要数据写入功能
 */
#pragma once
#include <stdint.h>
#include "WTSTypes.h"
#include "FasterDefs.h"

NS_WTP_BEGIN
class WTSTickData;
class WTSOrdQueData;
class WTSOrdDtlData;
class WTSTransData;
class WTSVariant;
class IBaseDataMgr;
struct WTSBarStruct;
struct WTSTickStruct;
struct WTSOrdDtlStruct;
struct WTSOrdQueStruct;
struct WTSTransStruct;

/**
 * @class IDataWriterSink
 * @brief 数据写入模块回调接口
 * @details 定义了数据写入模块与其他模块交互的回调接口。
 *          主要功能包括：
 *          - 基础数据管理器访问
 *          - 会话状态检查
 *          - 市场数据广播
 *          - 交易日期获取
 *          - 日志输出
 *          
 *          该接口由数据使用方实现，用于接收数据写入模块的通知和提供相关服务。
 */
class IDataWriterSink
{
public:
	/**
	 * @brief 获取基础数据管理器
	 * @details 提供对基础数据管理器的访问，用于获取合约信息、交易日历等基础数据。
	 * 
	 * @return IBaseDataMgr* 基础数据管理器指针
	 */
	virtual IBaseDataMgr* getBDMgr() = 0;

	/**
	 * @brief 检查会话是否可以接收数据
	 * @details 用于判断指定的交易会话是否处于可接收数据的状态。
	 * 
	 * @param sid 会话ID
	 * @return bool true表示可以接收数据，false表示不能接收
	 */
	virtual bool canSessionReceive(const char* sid) = 0;

	/**
	 * @brief 广播tick数据
	 * @details 将接收到的tick数据广播给所有订阅者。
	 *          用于实时数据分发。
	 * 
	 * @param curTick 当前tick数据
	 */
	virtual void broadcastTick(WTSTickData* curTick) = 0;

	/**
	 * @brief 广播委托队列数据
	 * @details 将接收到的委托队列数据广播给所有订阅者。
	 *          用于Level2委托队列数据分发。
	 * 
	 * @param curOrdQue 当前委托队列数据
	 */
	virtual void broadcastOrdQue(WTSOrdQueData* curOrdQue) = 0;

	/**
	 * @brief 广播逐笔委托数据
	 * @details 将接收到的逐笔委托数据广播给所有订阅者。
	 *          用于Level2逐笔委托数据分发。
	 * 
	 * @param curOrdDtl 当前逐笔委托数据
	 */
	virtual void broadcastOrdDtl(WTSOrdDtlData* curOrdDtl) = 0;

	/**
	 * @brief 广播逐笔成交数据
	 * @details 将接收到的逐笔成交数据广播给所有订阅者。
	 *          用于Level2逐笔成交数据分发。
	 * 
	 * @param curTrans 当前逐笔成交数据
	 */
	virtual void broadcastTrans(WTSTransData* curTrans) = 0;

	/**
	 * @brief 获取会话的合约集合
	 * @details 获取指定会话中包含的所有合约代码集合。
	 * 
	 * @param sid 会话ID
	 * @return CodeSet* 合约代码集合指针
	 */
	virtual CodeSet* getSessionComms(const char* sid) = 0;

	/**
	 * @brief 获取指定品种的交易日期
	 * @details 获取指定品种当前的交易日期。
	 * 
	 * @param pid 品种ID
	 * @return uint32_t 交易日期，格式为yyyyMMdd
	 */
	virtual uint32_t getTradingDate(const char* pid) = 0;

	/**
	 * @brief 输出数据写入模块日志
	 * @details 用于数据写入模块输出日志信息。
	 * 
	 * @param ll 日志级别
	 * @param message 日志消息内容
	 */
	virtual void outputLog(WTSLogLevel ll, const char* message) = 0;
};

/**
 * @class IHisDataDumper
 * @brief 历史数据导出器接口
 * @details 提供历史数据导出功能的接口，支持多种类型市场数据的导出。
 *          主要功能包括：
 *          - K线数据导出
 *          - Tick数据导出
 *          - Level2数据导出（委托队列、逐笔委托、逐笔成交）
 *          
 *          该接口用于将实时数据持久化保存为历史数据文件。
 */
class IHisDataDumper
{
public:
	/**
	 * @brief 导出历史K线数据
	 * @details 将K线数据导出保存到历史数据文件中。
	 * 
	 * @param stdCode 标准合约代码
	 * @param period K线周期字符串，如"m1"、"m5"、"d"等
	 * @param bars K线数据数组
	 * @param count K线数据数量
	 * @return bool 导出是否成功
	 */
	virtual bool dumpHisBars(const char* stdCode, const char* period, WTSBarStruct* bars, uint32_t count) = 0;
	
	/**
	 * @brief 导出历史tick数据
	 * @details 将tick数据导出保存到历史数据文件中。
	 * 
	 * @param stdCode 标准合约代码
	 * @param uDate 数据日期，格式为yyyyMMdd
	 * @param ticks tick数据数组
	 * @param count tick数据数量
	 * @return bool 导出是否成功
	 */
	virtual bool dumpHisTicks(const char* stdCode, uint32_t uDate, WTSTickStruct* ticks, uint32_t count) = 0;

	/**
	 * @brief 导出历史委托队列数据
	 * @details 将委托队列数据导出保存到历史数据文件中。
	 *          默认实现返回false，表示不支持。
	 * 
	 * @param stdCode 标准合约代码
	 * @param uDate 数据日期，格式为yyyyMMdd
	 * @param items 委托队列数据数组
	 * @param count 数据数量
	 * @return bool 导出是否成功，默认返回false
	 */
	virtual bool dumpHisOrdQue(const char* stdCode, uint32_t uDate, WTSOrdQueStruct* items, uint32_t count) { return false; }
	
	/**
	 * @brief 导出历史逐笔委托数据
	 * @details 将逐笔委托数据导出保存到历史数据文件中。
	 *          默认实现返回false，表示不支持。
	 * 
	 * @param stdCode 标准合约代码
	 * @param uDate 数据日期，格式为yyyyMMdd
	 * @param items 逐笔委托数据数组
	 * @param count 数据数量
	 * @return bool 导出是否成功，默认返回false
	 */
	virtual bool dumpHisOrdDtl(const char* stdCode, uint32_t uDate, WTSOrdDtlStruct* items, uint32_t count) { return false; }
	
	/**
	 * @brief 导出历史逐笔成交数据
	 * @details 将逐笔成交数据导出保存到历史数据文件中。
	 *          默认实现返回false，表示不支持。
	 * 
	 * @param stdCode 标准合约代码
	 * @param uDate 数据日期，格式为yyyyMMdd
	 * @param items 逐笔成交数据数组
	 * @param count 数据数量
	 * @return bool 导出是否成功，默认返回false
	 */
	virtual bool dumpHisTrans(const char* stdCode, uint32_t uDate, WTSTransStruct* items, uint32_t count) { return false; }
};

/// 扩展数据导出器映射表类型定义
typedef faster_hashmap<ShortKey, IHisDataDumper*> ExtDumpers;

/**
 * @class IDataWriter
 * @brief 数据写入接口
 * @details 数据写入模块提供的核心数据写入接口。
 *          主要功能包括：
 *          - 模块初始化和配置
 *          - 各类市场数据写入（tick、委托队列、逐笔委托、逐笔成交）
 *          - 历史数据转储
 *          - 扩展数据导出器管理
 *          - 当前tick数据获取
 *          
 *          该接口是数据写入模块的核心，由具体的数据存储实现类继承。
 */
class IDataWriter
{
public:
	IDataWriter():_sink(NULL){}

	/**
	 * @brief 初始化数据写入模块
	 * @details 使用配置参数初始化数据写入模块，设置回调接口。
	 * 
	 * @param params 模块配置参数
	 * @param sink 模块回调接口
	 * @return bool 初始化是否成功
	 */
	virtual bool init(WTSVariant* params, IDataWriterSink* sink) { _sink = sink; return true; }

	/**
	 * @brief 释放资源
	 * @details 释放数据写入模块占用的资源，进行清理工作。
	 */
	virtual void release() = 0;

	/**
	 * @brief 添加扩展数据导出器
	 * @details 添加外部的历史数据导出器，用于扩展数据导出功能。
	 * 
	 * @param id 导出器ID
	 * @param dumper 数据导出器指针
	 */
	void	add_ext_dumper(const char* id, IHisDataDumper* dumper) { _dumpers[id] = dumper; }

public:
	/**
	 * @brief 写入tick数据
	 * @details 将tick数据写入存储系统，是数据写入的核心接口。
	 * 
	 * @param curTick 当前tick数据
	 * @param procFlag 处理标志，控制数据处理方式
	 * @return bool 写入是否成功
	 */
	virtual bool writeTick(WTSTickData* curTick, uint32_t procFlag) = 0;

	/**
	 * @brief 写入委托队列数据
	 * @details 将委托队列数据写入存储系统。
	 *          默认实现返回false，表示不支持。
	 * 
	 * @param curOrdQue 当前委托队列数据
	 * @return bool 写入是否成功，默认返回false
	 */
	virtual bool writeOrderQueue(WTSOrdQueData* curOrdQue) { return false; }

	/**
	 * @brief 写入逐笔委托数据
	 * @details 将逐笔委托数据写入存储系统。
	 *          默认实现返回false，表示不支持。
	 * 
	 * @param curOrdDetail 当前逐笔委托数据
	 * @return bool 写入是否成功，默认返回false
	 */
	virtual bool writeOrderDetail(WTSOrdDtlData* curOrdDetail) { return false; }

	/**
	 * @brief 写入逐笔成交数据
	 * @details 将逐笔成交数据写入存储系统。
	 *          默认实现返回false，表示不支持。
	 * 
	 * @param curTrans 当前逐笔成交数据
	 * @return bool 写入是否成功，默认返回false
	 */
	virtual bool writeTransaction(WTSTransData* curTrans) { return false; }

	/**
	 * @brief 转储历史数据
	 * @details 将指定会话的实时数据转储为历史数据。
	 *          默认实现为空，子类可根据需要实现。
	 * 
	 * @param sid 会话ID
	 */
	virtual void transHisData(const char* sid) {}

	/**
	 * @brief 检查会话是否已处理
	 * @details 检查指定会话是否已完成数据处理。
	 *          默认返回true，表示已处理。
	 * 
	 * @param sid 会话ID
	 * @return bool true表示已处理，false表示未处理
	 */
	virtual bool isSessionProceeded(const char* sid) { return true; }

	/**
	 * @brief 获取当前tick数据
	 * @details 获取指定合约的最新tick数据。
	 * 
	 * @param code 合约代码
	 * @param exchg 交易所代码，默认为空字符串
	 * @return WTSTickData* 当前tick数据指针
	 */
	virtual WTSTickData* getCurTick(const char* code, const char* exchg = "") = 0;

protected:
	ExtDumpers			_dumpers;	///< 扩展数据导出器映射表
	IDataWriterSink*	_sink;		///< 数据写入回调接口
};

NS_WTP_END

/**
 * @typedef FuncCreateWriter
 * @brief 创建数据写入器函数指针类型
 * @details 用于动态库中创建数据写入器实例的函数指针。
 */
typedef wtp::IDataWriter* (*FuncCreateWriter)();

/**
 * @typedef FuncDeleteWriter
 * @brief 删除数据写入器函数指针类型
 * @details 用于动态库中删除数据写入器实例的函数指针。
 * 
 * @param writer 要删除的数据写入器引用
 */
typedef void(*FuncDeleteWriter)(wtp::IDataWriter* &writer);